[iOS] ローカル HTML の読み込み
車輪開発大好きおたいがです。こんにちは。(挨拶)
とある実務における実話なのですが、下記制限において動作する HTML アプリケーションを作ってほしい…という要望を受けました。
- http|https:// でアクセスするの禁止
オフライン環境での動作が必須 - iOS 端末限定
- 大人の都合で iOS Developer Program 使用禁止
UIWebView ラップするだけの自前アプリも NG
作業着手する前から絶望的な状況に立たされていたのですが、無事に乗り切れたので、肝心と思えた点のみ作業備忘録ということで残しておきます。
アプリケーションの選定
iOS 上で動作するブラウザアプリは、ファイルプロトコル (file://) 経由でローカル HTML にアクセスすることができないらしいので、既に世の中に出ているアプリを使用してローカル HTML を読み込むことにしました。
以下の候補は、いずれも iTunes のファイル共有機能を使用することで HTML の受け渡し、および、表示が可能です。
候補 1. DocAS Lite
https://itunes.apple.com/jp/app/docas-lite-pdf-bian-huan-pdf/id451036875
候補 2. DocAS
https://itunes.apple.com/jp/app/docas-pdf-bian-huan-pdf-zhu/id437110885
候補 3. FileApp
https://itunes.apple.com/jp/app/fileapp-file-manager-document/id297804694
DocAS の廉価版である DocAS Lite は、広告が表示されること ( HTML 表示中は表示されない ) と、管理できるドキュメント数に制限があること以外で特に気になる点はありませんでした。また、FileApp も試してみたのですが、<button> 要素をクリックしたときの表示挙動が DocAS と比較して怪しかったので、結果的に DocAS Lite を採用することにしました。( おそらく使用しているエンジンが違うのでしょう )
外部ファイルが読み込めない罠
無事に HTML が表示されたのは確認できましたが、JavaScript、CSS、画像など、外部ファイルを読み込むことができませんでした。なので、単一ソースでアプリケーションを完結させる必要があります。
JavaScript や CSS のコードは HTML に直接書き込めるということは広く知られていると思いますが、画像に関しても同じことが可能です。
データ URI スキームで Base64 形式の画像を読み込む
Google のウェブ検索結果で表示される画像にも採用されているデータ URI スキームを使用して、画像を HTML に埋め込むことにしました。
まずは画像を Base64 形式のに文字列にエンコードします。世の中に転がっているフリーソフトを使うなり、自前でツール作るなり、方法は色々あるので割愛しますが、たとえば私の Twitter アイコン…
これが以下のような文字列になります。
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 d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggiAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA=
あとは、変換した Base64 データをデータ URI スキームの書式 [*1] に変換して、<img> 要素に読み込ますだけです。
*1 Data URI scheme - Wikipedia | 書式 より
http://ja.wikipedia.org/wiki/Data_URI_scheme#.E6.9B.B8.E5.BC.8F
data:[
][;charset= ][;base64],
before
<img src="taiga.png" />
after
<img src="data:image/png;base64,iVBORw0KGg<中略>ICAgICA=" />
これで画像が HTML に埋め込まれます。ただし、HTML の容量が大きくなります。
実際に使用した ( できた ) フレームワーク、機能
すべて、ひとつの HTML に埋め込む必要がありましたが、問題なく動いてくれました。
- jQuery
- AngularJS
- Bootstrap
Glyphicon の使用可否は不明 - localStorage
5MB の容量制限あり
まとめ
自分が思っていた以上に動作してくれました。
たとえば、localStorage にデータを蓄積させるような簡易 Web アプリを構築するときには、この手が意外と使えるかもしれません。
また、厳しい制約の中で試行錯誤するのはなかなか面白いかも…などと思いました。